/*
 * Copyright (c) 2007 jNetX.
 * http://www.jnetx.com
 * All rights reserved.
 *
 * This software is the confidential and proprietary information of
 * jNetX. You shall not disclose such Confidential Information and
 * shall use it only in accordance with the terms of the license
 * agreement you entered into with jNetX.
 *
 * $Id$
 */
package com.jnetx.javax.sip;

import com.jnetx.javax.sip.message.SIPRequest;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.sip.*;
import javax.sip.message.Request;
import java.text.ParseException;

/**
 * A client transaction is used by a User Agent Client application to send
 * Request messages to a User Agent Server application.
 * The client transaction is also used to match Responses from the User Agent
 * Server to fire Response events to the SipListener for a specific client
 * transaction. This interfaces enables an application to send a
 * {@link javax.sip.message.Request}'s statefully. A new client transaction
 * is generated by the application calling the
 * {@link SipProvider#getNewClientTransaction(Request)} method.
 * <p/>
 * A client transaction of the transaction layer is represented by a finite
 * state machine that is constructed to process a particular request under
 * the covers of a stateful SipProvider. The transaction layer handles
 * application-layer retransmissions, matching of responses to requests, and
 * application-layer timeouts. Any task that a User Agent Client
 * accomplishes takes place using a series of transactions.
 * <p/>
 * The client transaction must be unique within the underlying
 * implementation. A common way to create this value is to compute a
 * cryptographic hash of the To tag, From tag, Call-ID header field, the
 * Request-URI of the request received (before translation), the topmost Via
 * header, and the sequence number from the CSeq header field, in addition to
 * any Proxy-Require and Proxy-Authorization header fields that may be present.
 * The algorithm used to compute the hash is implementation-dependent.
 * <p/>
 * For the detailed client transaction state machines refer to Chapter
 * 17 of <a href="http://www.ietf.org/rfc/rfc3261.txt">RFC 3261</a>, the
 * allowable transitions are summarized below:
 * <p/>
 * <b>Invite Transaction:</b><br>
 * Calling --> Proceeding --> Completed --> Terminated
 * <p/>
 * <b>Non-Invite Transaction:</b><br>
 * Trying --> Proceeding --> Completed --> Terminated
 *
 * @author <a href="mailto:dparhonin@jnetx.ru">Dmitry Parhonin</a>
 * @version $Revision$
 */
public class ClientTransactionImpl implements ClientTransaction {
    private final static Log logger = LogFactory.getLog("ClientTransactionImpl");

    private final Request request;
    private final SipProvider provider;

    public ClientTransactionImpl(Request request, SipProvider provider) {
        this.request = request;
        this.provider = provider;
    }

    /**
     * {@inheritDoc}
     */
    public void sendRequest() throws SipException {
        provider.sendRequest(request);
    }

    public Request createCancel() throws SipException {
        final Request cancel = new SIPRequest();
        try {
            cancel.setMethod("CANCEL");
        } catch (ParseException e) {
            final String message = "Cannot set CANCEL method!";
            logger.error(message, e);
            throw new AssertionError(message);
        }
        return cancel;
    }

    /**
     * @deprecated
     */
    public Request createAck() throws SipException {
        final Request ack = new SIPRequest();
        try {
            ack.setMethod("ACK");
        } catch (ParseException e) {
            final String message = "Cannot set ACK method!";
            logger.error(message, e);
            throw new AssertionError(message);
        }
        return ack;
    }

    public Dialog getDialog() {
        return null;
    }

    public TransactionState getState() {
        return null;
    }

    public int getRetransmitTimer() throws UnsupportedOperationException {
        return 0;
    }

    public void setRetransmitTimer(int i) throws UnsupportedOperationException {

    }

    public String getBranchId() {
        return null;
    }

    public Request getRequest() {
        return null;
    }

    public void setApplicationData(Object object) {

    }

    public Object getApplicationData() {
        return null;
    }

    public void terminate() throws ObjectInUseException {

    }
}
/*
 * $Log$
 */